*** /tmp/,RCSt1a27031	Thu Aug 24 00:01:21 1989
--- proc.c	Thu Aug 17 17:29:27 1989
***************
*** 24,29 ****
--- 24,33 ----
  #include "proc.h"
  #include "k_proto.h"
  
+ #ifdef ATARI_ST
+ unsigned long busy_map = 0L;
+ #endif
+ 
  static int mini_rec(int, struct proc *, int, message *);
  static void cp_mess(int, struct proc *, message *, struct proc *, message *); 
  
***************
*** 46,52 ****
  message *m_ptr;			/* interrupt message to send to the task */
  {
  /* An interrupt has occurred.  Schedule the task that handles it. */
! 
  
  #ifdef i8088
    /* Re-enable the 8259A interrupt controller. */
--- 50,59 ----
  message *m_ptr;			/* interrupt message to send to the task */
  {
  /* An interrupt has occurred.  Schedule the task that handles it. */
! #if 1
!   int i, n;
!   unsigned long old_map, this_bit;
! #endif
  
  #ifdef i8088
    /* Re-enable the 8259A interrupt controller. */
***************
*** 56,63 ****
--- 63,101 ----
  	  port_out(INT2_CTL, ENABLE);
  #endif
  
+ #if 0
    /* Try to send the interrupt message to the indicated task. */
    mini_send(HARDWARE, proc_addr(HARDWARE), task, m_ptr);
+ #else
+   /* Try to send the interrupt message to the indicated task. */
+   this_bit = 1 << (-task);
+   if (mini_send(HARDWARE, proc_addr(HARDWARE), task, m_ptr) != OK) {
+ 	/* The message could not be sent to the task; it was not waiting. */
+ 	old_map = busy_map;	/* save original map of busy tasks */
+ 	if (task == CLOCK) {
+ 		lost_ticks++;
+ 	} else {
+ 		busy_map |= this_bit;		/* mark task as busy */
+ 		task_mess[-task] = m_ptr;	/* record message pointer */
+ 	}
+   } else {
+ 	/* Hardware interrupt was successfully sent as a message. */
+ 	busy_map &= ~this_bit;	/* turn off the bit in case it was on */
+ 	old_map = busy_map;
+   }
+ 
+   /* See if any tasks that were previously busy are now listening for msgs. */
+   if (old_map != 0) {
+ 	for (i = 2, this_bit = 4; i <= NR_TASKS; this_bit <<= 1, i++) {
+ 		/* Check each task looking for one with a pending interrupt. */
+ 		if ( old_map & this_bit ) {
+ 			/* Task 'i' has a pending interrupt. */
+ 			n = mini_send(HARDWARE, proc_addr(HARDWARE), -i, task_mess[i]);
+ 			if (n == OK) busy_map &= ~this_bit;
+ 		}
+ 	}
+   }
+ #endif
  
  #ifndef ATARI_ST
    /* If a task has just been readied and a user is running, run the task. */
***************
*** 103,109 ****
    }
  
    if (function & RECEIVE) {
! 	n = mini_rec(caller,  rp, src_dest, m_ptr);  /* func = RECEIVE or BOTH */
  	rp->p_reg[RET_REG] = n;
    }
  }
--- 141,147 ----
    }
  
    if (function & RECEIVE) {
! 	n = mini_rec(caller, rp, src_dest, m_ptr);  /* func = RECEIVE or BOTH */
  	rp->p_reg[RET_REG] = n;
    }
  }
***************
*** 127,133 ****
    vir_clicks vlo, vhi;		/* virtual clicks containing message to send */
    vir_clicks len;		/* length of data segment in clicks */
    int s;
! 
    /* User processes are only allowed to send to FS and MM.  Check for this. */
    if (caller >= LOW_USER && (dest != FS_PROC_NR && dest != MM_PROC_NR))
  	return(E_BAD_DEST);
--- 165,171 ----
    vir_clicks vlo, vhi;		/* virtual clicks containing message to send */
    vir_clicks len;		/* length of data segment in clicks */
    int s;
!   
    /* User processes are only allowed to send to FS and MM.  Check for this. */
    if (caller >= LOW_USER && (dest != FS_PROC_NR && dest != MM_PROC_NR))
  	return(E_BAD_DEST);
***************
*** 152,183 ****
    }
  
    /* Check to see if 'dest' is blocked waiting for this message. */
!   s = lock();
!   if ( (dest_ptr->p_flags & RECEIVING) &&
! 		(dest_ptr->p_flags & SENDING) == 0 &&
! 		(dest_ptr->p_getfrom == ANY || dest_ptr->p_getfrom == caller) ) {
  	/* Destination is indeed waiting for this message. */
  	CopyMess(caller, caller_ptr, m_ptr, dest_ptr, dest_ptr->p_messbuf);
  	dest_ptr->p_flags &= ~RECEIVING;	/* deblock destination */
-  	restore(s);
  	if (dest_ptr->p_flags == 0) ready(dest_ptr);
    } else {
  	/* Destination is not waiting.  Block and queue caller. */
! 	if (caller == HARDWARE) {
! 		restore(s);
! 		if (dest == CLOCK)
! 			lost_ticks++;
! #ifdef NEEDED
! 		else if (task_mess[-dest])
! 			printf("interrupt for task %d lost\n", dest);
! #endif
! 		else
! 			task_mess[-dest] = m_ptr;	/* record message pointer */
! 		return(E_OVERRUN);
! 	}
  	caller_ptr->p_messbuf = m_ptr;
! 	if (caller_ptr->p_flags == 0)
! 		unready(caller_ptr);
  	caller_ptr->p_flags |= SENDING;
  
  	/* Process is now blocked.  Put in on the destination's queue. */
--- 190,211 ----
    }
  
    /* Check to see if 'dest' is blocked waiting for this message. */
! /*   s = lock(); */
!   if ( (dest_ptr->p_flags & RECEIVING) && (dest_ptr->p_flags & SENDING) == 0 &&
! 		(dest_ptr->p_getfrom == ANY || dest_ptr->p_getfrom == caller)){
  	/* Destination is indeed waiting for this message. */
  	CopyMess(caller, caller_ptr, m_ptr, dest_ptr, dest_ptr->p_messbuf);
  	dest_ptr->p_flags &= ~RECEIVING;	/* deblock destination */
  	if (dest_ptr->p_flags == 0) ready(dest_ptr);
    } else {
  	/* Destination is not waiting.  Block and queue caller. */
!       if (caller == HARDWARE)
!       {
! 	  /* restore(s); */
! 	  return(E_OVERRUN);
!       }
  	caller_ptr->p_messbuf = m_ptr;
! 	if (caller_ptr->p_flags == 0) unready(caller_ptr);
  	caller_ptr->p_flags |= SENDING;
  
  	/* Process is now blocked.  Put in on the destination's queue. */
***************
*** 189,195 ****
  		next_ptr->p_sendlink = caller_ptr;
  	}
  	caller_ptr->p_sendlink = NIL_PROC;
! 	restore(s);
    }
    return(OK);
  }
--- 217,223 ----
  		next_ptr->p_sendlink = caller_ptr;
  	}
  	caller_ptr->p_sendlink = NIL_PROC;
! /*        restore(s); */
    }
    return(OK);
  }
***************
*** 211,231 ****
   * Calls from the tasks, MM, and FS are trusted.
   */
  
!   register struct proc *sender_ptr, *prev_ptr;
    int sender;
! 
    if ((caller_ptr->p_flags & SENDING) == 0) {
!      if (caller < 0 && task_mess[-caller]) {
  	/* we have a HARDWARE message waiting */
  	if (src == ANY || src == HARDWARE) {
  		sender_ptr = proc_addr(HARDWARE);
  		CopyMess(HARDWARE, sender_ptr, task_mess[-caller],
  					caller_ptr, m_ptr);
! 		task_mess[-caller] = 0;
  		return(OK);
  	}
       }
!      /* Check to see if a message from desired source is already available. */
       sender_ptr = caller_ptr->p_callerq;
       while (sender_ptr != NIL_PROC) {
  	sender = (sender_ptr - proc) - NR_TASKS;
--- 239,261 ----
   * Calls from the tasks, MM, and FS are trusted.
   */
  
!   register struct proc *sender_ptr, *previous_ptr;
    int sender;
!   unsigned long this_bit;
!   
!   /* Check to see if a message from desired source is already available. */
    if ((caller_ptr->p_flags & SENDING) == 0) {
!      if (caller < 0 && (busy_map & (this_bit = (1L << (-caller))))) {
  	/* we have a HARDWARE message waiting */
  	if (src == ANY || src == HARDWARE) {
  		sender_ptr = proc_addr(HARDWARE);
  		CopyMess(HARDWARE, sender_ptr, task_mess[-caller],
  					caller_ptr, m_ptr);
! 		busy_map &= ~this_bit;
  		return(OK);
  	}
       }
!      /* not a hardware message, but one is avail */
       sender_ptr = caller_ptr->p_callerq;
       while (sender_ptr != NIL_PROC) {
  	sender = (sender_ptr - proc) - NR_TASKS;
***************
*** 232,247 ****
  	if (src == ANY || src == sender) {
  		/* An acceptable message has been found. */
  		CopyMess(sender, sender_ptr, sender_ptr->p_messbuf,
! 					caller_ptr, m_ptr);
  		sender_ptr->p_flags &= ~SENDING;	/* deblock sender */
  		if (sender_ptr->p_flags == 0) ready(sender_ptr);
  		if (sender_ptr == caller_ptr->p_callerq)
  			caller_ptr->p_callerq = sender_ptr->p_sendlink;
  		else
! 			prev_ptr->p_sendlink = sender_ptr->p_sendlink;
  		return(OK);
  	}
! 	prev_ptr = sender_ptr;
  	sender_ptr = sender_ptr->p_sendlink;
       }
    }
--- 262,277 ----
  	if (src == ANY || src == sender) {
  		/* An acceptable message has been found. */
  		CopyMess(sender, sender_ptr, sender_ptr->p_messbuf,
! 		         caller_ptr, m_ptr);
  		sender_ptr->p_flags &= ~SENDING;	/* deblock sender */
  		if (sender_ptr->p_flags == 0) ready(sender_ptr);
  		if (sender_ptr == caller_ptr->p_callerq)
  			caller_ptr->p_callerq = sender_ptr->p_sendlink;
  		else
! 			previous_ptr->p_sendlink = sender_ptr->p_sendlink;
  		return(OK);
  	}
! 	previous_ptr = sender_ptr;
  	sender_ptr = sender_ptr->p_sendlink;
       }
    }
***************
*** 249,265 ****
    /* No suitable message is available.  Block the process trying to receive. */
    caller_ptr->p_getfrom = src;
    caller_ptr->p_messbuf = m_ptr;
!   if (caller_ptr->p_flags == 0)
! 	unready(caller_ptr);
    caller_ptr->p_flags |= RECEIVING;
  
    /* If MM has just blocked and there are kernel signals pending, now is the
     * time to tell MM about them, since it will be able to accept the message.
     */
!   if (sig_procs > 0 && caller == MM_PROC_NR && src == ANY) 
!   {
!       inform();
!       pick_proc();
    }
    return(OK);
  }
--- 279,293 ----
    /* No suitable message is available.  Block the process trying to receive. */
    caller_ptr->p_getfrom = src;
    caller_ptr->p_messbuf = m_ptr;
!   if (caller_ptr->p_flags == 0) unready(caller_ptr);
    caller_ptr->p_flags |= RECEIVING;
  
    /* If MM has just blocked and there are kernel signals pending, now is the
     * time to tell MM about them, since it will be able to accept the message.
     */
!   if (sig_procs > 0 && caller == MM_PROC_NR && src == ANY) {
! 	inform();
! 	pick_proc();
    }
    return(OK);
  }
***************
*** 315,335 ****
   */
  
    register int q;		/* TASK_Q, SERVER_Q, or USER_Q */
!   register int s;
! 
!   s = lock();			/* disable interrupts */
! 
!   DEBUG(if (rp->p_flags != 0)
! 	panic("ready with flags. proc =", (rp-proc)-NR_TASKS);
!   );
!   DEBUG({ register struct proc *xp;
! 	for (q = 0; q < NQ; q++)
! 		for (xp = rdy_head[q]; xp != NIL_PROC; xp = xp->p_nextready)
! 			if (xp == rp)
! 				panic("ready, but already ready. proc =",
! 					(rp-proc)-NR_TASKS);
!   });
  
    if (rp < &proc[NR_TASKS])
  	q = TASK_Q;
    else if (rp < &proc[NR_TASKS+LOW_USER])
--- 343,351 ----
   */
  
    register int q;		/* TASK_Q, SERVER_Q, or USER_Q */
!   int  old_state;
  
+   old_state = lock();		/* disable interrupts */
    if (rp < &proc[NR_TASKS])
  	q = TASK_Q;
    else if (rp < &proc[NR_TASKS+LOW_USER])
***************
*** 348,354 ****
  	rdy_tail[q]->p_nextready = rp;	/* add to tail of nonempty queue */
    rdy_tail[q] = rp;		/* new entry has no successor */
    rp->p_nextready = NIL_PROC;
!   restore(s);			/* restore interrupts to previous state */
  }
  
  
--- 364,370 ----
  	rdy_tail[q]->p_nextready = rp;	/* add to tail of nonempty queue */
    rdy_tail[q] = rp;		/* new entry has no successor */
    rp->p_nextready = NIL_PROC;
!   restore(old_state);		/* restore interrupts to previous state */
  }
  
  
***************
*** 361,374 ****
  /* A process has blocked. */
  
    register struct proc *xp;
!   int q, s;
  
!   s = lock();			/* disable interrupts */
  
-   DEBUG(if (rp->p_flags != 0)
- 	panic("unready with flags. proc =", (rp-proc)-NR_TASKS);
-   );
- 
    if (rp < &proc[NR_TASKS])
  	q = TASK_Q;
    else if (rp < &proc[NR_TASKS+LOW_USER])
--- 377,386 ----
  /* A process has blocked. */
  
    register struct proc *xp;
!   int q, old_state;
  
!   old_state = lock();			/* disable interrupts */
  
    if (rp < &proc[NR_TASKS])
  	q = TASK_Q;
    else if (rp < &proc[NR_TASKS+LOW_USER])
***************
*** 381,396 ****
  	q = USER_Q;
  
    if ( (xp = rdy_head[q]) == NIL_PROC) {
! 	restore(s);
  	return;
    }
    if (xp == rp) {
  	/* Remove head of queue */
  	rdy_head[q] = xp->p_nextready;
! #ifdef ATARI_ST
! 	if (rp == proc_ptr)
! #endif
! 		pick_proc();
    } else {
  	/* Search body of queue.  A process can be made unready even if it is
  	 * not running by being sent a signal that kills it.
--- 393,405 ----
  	q = USER_Q;
  
    if ( (xp = rdy_head[q]) == NIL_PROC) {
! 	restore(old_state);
  	return;
    }
    if (xp == rp) {
  	/* Remove head of queue */
  	rdy_head[q] = xp->p_nextready;
! 	if (rp == proc_ptr) pick_proc();
    } else {
  	/* Search body of queue.  A process can be made unready even if it is
  	 * not running by being sent a signal that kills it.
***************
*** 397,405 ****
  	 */
  	while (xp->p_nextready != rp)
  		if ( (xp = xp->p_nextready) == NIL_PROC) {
! 			DEBUG(panic("unready, but not ready, proc =",
! 				(rp-proc)-NR_TASKS));
! 			restore(s);
  			return;
  		}
  	xp->p_nextready = xp->p_nextready->p_nextready;
--- 406,412 ----
  	 */
  	while (xp->p_nextready != rp)
  		if ( (xp = xp->p_nextready) == NIL_PROC) {
! 			restore(old_state);
  			return;
  		}
  	xp->p_nextready = xp->p_nextready->p_nextready;
***************
*** 406,412 ****
  	while (xp->p_nextready != NIL_PROC) xp = xp->p_nextready;
  	rdy_tail[q] = xp;
    }
!   restore(s);			/* restore interrupts to previous state */
  }
  
  
--- 413,419 ----
  	while (xp->p_nextready != NIL_PROC) xp = xp->p_nextready;
  	rdy_tail[q] = xp;
    }
!   restore(old_state);			/* restore interrupts to prev state */
  }
  
  
***************
*** 420,430 ****
   * possibly promoting another user to head of the queue.
   */
  
!   register int s;
  
!   s = lock();			/* disable interrupts */
    if (rdy_head[USER_Q] == NIL_PROC) {
! 	restore(s);		/* restore interrupts to previous state */
  	return;
    }
  
--- 427,437 ----
   * possibly promoting another user to head of the queue.
   */
  
!   int old_state;
  
!   old_state = lock();			/* disable interrupts */
    if (rdy_head[USER_Q] == NIL_PROC) {
! 	restore(old_state);		/* restore interrupts to prev state */
  	return;
    }
  
***************
*** 434,440 ****
    rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
    rdy_tail[USER_Q]->p_nextready = NIL_PROC;
    pick_proc();
!   restore(s);			/* restore interrupts to previous state */
  }
  
  #ifdef ATARI_ST
--- 441,447 ----
    rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
    rdy_tail[USER_Q]->p_nextready = NIL_PROC;
    pick_proc();
!   restore(old_state);			/* restore interrupts to prev state */
  }
  
  #ifdef ATARI_ST
*** /tmp/,RCSt1a27031	Thu Aug 24 00:02:07 1989
--- stvdu.c	Thu Aug 17 17:56:05 1989
***************
*** 74,89 ****
  {
    if (tp->tty_outleft == 0)
  	return(1);
    vducursor(0);
    do {
! 	if (tp->tty_inhibited == TRUE) {
! 		vducursor(1);
! 		return(0);
! 	}
! 	vduput(*((char *)tp->tty_phys));
  				/* write 1 byte to terminal */
! 	tp->tty_phys++;		/* advance physical data pointer */
! 	tp->tty_cum++;		/* number of characters printed */
    } while (--tp->tty_outleft != 0);
    vducursor(1);
    return(1);
--- 74,93 ----
  {
    if (tp->tty_outleft == 0)
  	return(1);
+   if (tp->tty_inhibited == TRUE)
+       return(0);
+ 
    vducursor(0);
    do {
!       if (tp->tty_inhibited == TRUE) 
!       {
! 	  vducursor(1);
! 	  return(0);
!       }
!       vduput(*((char *)tp->tty_phys));
  				/* write 1 byte to terminal */
!       tp->tty_phys++;		/* advance physical data pointer */
!       tp->tty_cum++;		/* number of characters printed */
    } while (--tp->tty_outleft != 0);
    vducursor(1);
    return(1);
***************
*** 190,196 ****
--- 194,204 ----
  	return;
    case 012: /* LF */
  	if (mode & CRMOD)
+ #if 0
  		vduput('\r');
+ #else
+ 	        moveto(v->crow, 0);
+ #endif
    case 013: /* VT */
    case 014: /* FF */
  	if (v->crow == v->nrow - 1) {
***************
*** 480,487 ****
--- 488,499 ----
    if (c >= '0' && c <= '9') {
  	i = 0;
  	do {
+ #if 0
  		i *= 10;
  		i += (c - '0');
+ #else
+ 		i = (((i << 2) + i) << 1) + (c - '0');
+ #endif		
  		c = *v->next++;
  	} while (c >= '0' && c <= '9');
    }
***************
*** 508,519 ****
    src = (long*)&v->vram[r1 * v->bytr];
    dst = (long*)&v->vram[r2 * v->bytr];
    i = v->bytr >> 4;	/* 16 bytes per iteration */
!   while (--i >= 0) {
  	*dst++ = *src++;
  	*dst++ = *src++;
  	*dst++ = *src++;
  	*dst++ = *src++;
!   }
  }
  
  /*
--- 520,531 ----
    src = (long*)&v->vram[r1 * v->bytr];
    dst = (long*)&v->vram[r2 * v->bytr];
    i = v->bytr >> 4;	/* 16 bytes per iteration */
!   do {
  	*dst++ = *src++;
  	*dst++ = *src++;
  	*dst++ = *src++;
  	*dst++ = *src++;
!   } while(--i > 0);
  }
  
  /*
***************
*** 594,605 ****
  
    p = (long*)&v->vram[r * v->bytr];
    i = v->bytr >> 4;	/* 16 bytes per iteration */
!   while (--i >= 0) {
  	*p++ = 0L;
  	*p++ = 0L;
  	*p++ = 0L;
  	*p++ = 0L;
!   }
  }
  
  /*
--- 606,617 ----
  
    p = (long*)&v->vram[r * v->bytr];
    i = v->bytr >> 4;	/* 16 bytes per iteration */
!   do {
  	*p++ = 0L;
  	*p++ = 0L;
  	*p++ = 0L;
  	*p++ = 0L;
!   }   while (--i > 0) ;
  }
  
  /*
***************
*** 644,655 ****
--- 656,699 ----
  {
    register struct vduinfo *v = &vduinfo;
  
+ #ifdef NO_AUTOWRAP
    if (r < 0 || r >= v->nrow || c < 0 || c > NCOL)
+ #else
+   if (r < 0 || r >= v->nrow || c > NCOL)
+ #endif
  	return;
+ 
+ #ifndef NO_AUTOWRAP
+   if (c < 0)		/* wrap backwards to previous line */
+   {
+       if(r == 0)
+ 	  moveto(0, 0);
+       else
+ 	  moveto(r - 1, NCOL - 1);
+       return;
+   }
+ #endif
+   
    v->crow = r;
    v->ccol = c;
    if (c == NCOL)
+ #ifdef NO_AUTOWRAP
  	c--;			/* show cursor in last column */
+ #else
+   {
+     v->ccol = c = 0;		/* auto wrap */
+     if(r == v->nrow - 1)
+     {
+ 	register int i;
+ 	for (i = 0; i < r; i++)
+ 	    cpyline(i + 1, i);
+ 	clrline(i);
+     } else
+ 	v->crow = ++r;
+     v->curs = &v->vram[(r * v->bytr)];
+     return;
+   }
+ #endif
  
    if (!v->mono) {		/* 0->0, 1->1, 2->4, 3->5, 4->8, ... */
  	c <<= 1;
*** /tmp/,RCSt1a27031	Thu Aug 24 00:02:11 1989
--- stwini.c	Thu Aug 17 00:50:55 1989
***************
*** 111,116 ****
--- 111,119 ----
  
  /* Parameters for the disk drive. */
  #define SECTOR_SIZE	512	/* physical sector size in bytes */
+ #define SECTOR_MASK	(SECTOR_SIZE - 1) /* mask for modulus */
+ #define SECTOR_SHIFT	9	/* 2^SECTOR_SHIFT == SECTOR_SIZE */
+ 
  #define NR_DRIVES	8	/* maximum number of drives */
  #define	MAX_MINOR	(NR_DRIVES<<3)
  #define MAX_ERRORS	10	/* how often to try rd/wt before quitting */
***************
*** 144,150 ****
   *===========================================================================*/
  PUBLIC void winchester_task()
  {
!   register	r, drive, minor, caller, procno;
    long offset;	
  
   /*
--- 147,154 ----
   *===========================================================================*/
  PUBLIC void winchester_task()
  {
!   register int	r, drive, minor, caller, procno;
!   register struct pi *p;
    long offset;	
  
   /*
***************
*** 158,186 ****
  	minor = drive << 3;
  
  /* virtual drive 0 == physical drive */
  	/* read sector 0 of the drive and copy the partition info */
! 	pi[minor].pi_size = 1;
  	dmagrab(WINCHESTER, hdcint);
  	r = do_xfer(drive, (phys_bytes)&hi, 0L, 1, DISK_READ);
  	dmafree(WINCHESTER);
  	if (r != OK) {
! 		pi[minor].pi_size = 0;
  		continue;
  	}
! 	for (r = 0, minor++; r < NPARTS; r++, minor++) {
! 		pi[minor] = hi.hd_pi[r];
! 		if (pi[minor].pi_flag == PI_INVALID)
! 			pi[minor].pi_size = 0;
! 		if( pi[minor].pi_size )
! 			offset = pi[minor].pi_start + pi[minor].pi_size ;
  	}
  /* partition 7 is the whole physical disk */
! 	pi[minor+2].pi_size = hi.hd_size;
  #if HCJ_PARTITION
  /* change partition 5 to be the whole physical disk */
  /* but if a virtual drive is found, this is changed to the virtual size */
! 	pi[minor].pi_size = hi.hd_size;
! 	minor += 2;
  
  	if(drive == 0 && pi[3].pi_size > 512) {
  		pi[3].pi_size -= 512;
--- 162,191 ----
  	minor = drive << 3;
  
  /* virtual drive 0 == physical drive */
+ 
  	/* read sector 0 of the drive and copy the partition info */
! 	p = &pi[minor];
! 	p->pi_size = 1;
  	dmagrab(WINCHESTER, hdcint);
  	r = do_xfer(drive, (phys_bytes)&hi, 0L, 1, DISK_READ);
  	dmafree(WINCHESTER);
  	if (r != OK) {
! 		p->pi_size = 0;
  		continue;
  	}
! 	for (r = 0, p++; r < NPARTS; r++, p++) {
! 		*p = hi.hd_pi[r];
! 		if (p->pi_flag == PI_INVALID)
! 			p->pi_size = 0;
! 		if( p->pi_size )
! 			offset = p->pi_start + p->pi_size ;
  	}
  /* partition 7 is the whole physical disk */
! 	(p+2)->pi_size = hi.hd_size;
  #if HCJ_PARTITION
  /* change partition 5 to be the whole physical disk */
  /* but if a virtual drive is found, this is changed to the virtual size */
! 	p->pi_size = hi.hd_size;
  
  	if(drive == 0 && pi[3].pi_size > 512) {
  		pi[3].pi_size -= 512;
***************
*** 188,194 ****
  		pi[6].pi_start = pi[3].pi_start + pi[3].pi_size;
  	}
  /* virtual drive 1 */
! 	minor = (drive+1) << 3;
  	if ( hi.bsl_start != 0L ) {
  printf("Drive %d, virtual omitted: bsl_start=%lx offset=%lx \n",
   DRIVE(drive),hi.bsl_start,offset);
--- 193,199 ----
  		pi[6].pi_start = pi[3].pi_start + pi[3].pi_size;
  	}
  /* virtual drive 1 */
! 	p = &pi[((drive+1) << 3)];
  	if ( hi.bsl_start != 0L ) {
  printf("Drive %d, virtual omitted: bsl_start=%lx offset=%lx \n",
   DRIVE(drive),hi.bsl_start,offset);
***************
*** 197,220 ****
  	if(offset > hi.hd_size)
  		continue;
  	/* read sector 0 of the (virtual) drive and copy the partition info */
! 	pi[minor].pi_start = offset;
! 	pi[minor].pi_size = 1;
  	dmagrab(WINCHESTER, hdcint);
  	r = do_xfer(drive, (phys_bytes)&hi, offset, 1, DISK_READ);
  	dmafree(WINCHESTER);
  	if (r != OK) {
! 		pi[minor].pi_size = 0;
  		continue;
  	}
! 	for (r = 0, minor++; r < NPARTS; r++, minor++) {
! 		pi[minor] = hi.hd_pi[r];
! 		pi[minor].pi_start += offset;
! 		if (pi[minor].pi_flag == PI_INVALID)
! 			pi[minor].pi_size = 0;
  	}
  /* set up partition 5 as whole virtual disk */
! 	pi[minor].pi_start = offset;
! 	pi[minor].pi_size = hi.hd_size - offset +1;
  
  /* change 'real' disk (virtural 0) to have only its own size in part. 5 */
  	pi[(drive<<3)+5].pi_size = offset;
--- 202,225 ----
  	if(offset > hi.hd_size)
  		continue;
  	/* read sector 0 of the (virtual) drive and copy the partition info */
! 	p->pi_start = offset;
! 	p->pi_size = 1;
  	dmagrab(WINCHESTER, hdcint);
  	r = do_xfer(drive, (phys_bytes)&hi, offset, 1, DISK_READ);
  	dmafree(WINCHESTER);
  	if (r != OK) {
! 		p->pi_size = 0;
  		continue;
  	}
! 	for (r = 0, p++; r < NPARTS; r++, p++) {
! 		*p = hi.hd_pi[r];
! 		p->pi_start += offset;
! 		if (p->pi_flag == PI_INVALID)
! 			p->pi_size = 0;
  	}
  /* set up partition 5 as whole virtual disk */
! 	p->pi_start = offset;
! 	p->pi_size = hi.hd_size - offset +1;
  
  /* change 'real' disk (virtural 0) to have only its own size in part. 5 */
  	pi[(drive<<3)+5].pi_size = offset;
***************
*** 227,243 ****
   * The next physical drive is hd16, with hd16-hd24, and hd24-hd31 
   * the same as hd0-hd7 and hd8-hd15. Etc., for each addl drive.
   */
! 	for (r = 0, minor=((drive+1) << 3); r < 8; r++, minor++) {
! 		pi[minor] = hi.hd_supra[r];
!                 if (pi[minor].pi_flag == PI_INVALID)
! 			pi[minor].pi_size = 0;
  /*
   * HCJ: this is an added test of sanity:
   * start and end of partition must be < hd_size 
   */
! 		if (pi[minor].pi_start >= hi.hd_size || /* start is too big */
! 		    pi[minor].pi_start + pi[minor].pi_size -1 >= hi.hd_size)
! 			pi[minor].pi_size = 0;
  	}
  #endif
  				
--- 232,248 ----
   * The next physical drive is hd16, with hd16-hd24, and hd24-hd31 
   * the same as hd0-hd7 and hd8-hd15. Etc., for each addl drive.
   */
! 	for (r = 0,p= &pi[((drive+1) << 3)]; r < 8; r++, p++) {
! 		*p = hi.hd_supra[r];
!                 if (pi->pi_flag == PI_INVALID)
! 			p->pi_size = 0;
  /*
   * HCJ: this is an added test of sanity:
   * start and end of partition must be < hd_size 
   */
! 		if (p->pi_start >= hi.hd_size || /* start is too big */
! 		    p->pi_start + p->pi_size -1 >= hi.hd_size)
! 			p->pi_size = 0;
  	}
  #endif
  				
***************
*** 292,298 ****
  register message *mp;
  {
    register struct proc	*rp;
!   register		r, errors, count, rw, drive, minor;
    register long		secnum;
    register phys_bytes	address;
    extern phys_bytes	umap(struct proc *, int, long, long);
--- 297,304 ----
  register message *mp;
  {
    register struct proc	*rp;
!   register int		r, errors, count, rw, drive, minor;
!   register struct pi    *p;
    register long		secnum;
    register phys_bytes	address;
    extern phys_bytes	umap(struct proc *, int, long, long);
***************
*** 302,327 ****
    drive = minor >> 3;
    if (drive < 0 || drive >= NR_DRIVES)
  	return(EIO);
!   if (pi[minor].pi_size == 0)
  	return(EIO);
!   if ((mp->POSITION % SECTOR_SIZE) != 0)
  	return(EINVAL);
!   secnum = (long)(mp->POSITION / SECTOR_SIZE);
    count = mp->COUNT;
!   if ((count % SECTOR_SIZE) != 0)
  	return(EINVAL);
    rp = proc_addr(mp->PROC_NR);
    address = umap(rp, D, (vir_bytes) mp->ADDRESS, (vir_bytes) count);
    if (address == 0)
  	return(EINVAL);
!   count /= SECTOR_SIZE;
    TRACE(printf("hd%d: %s: sec=%D; cnt=%d\n",
  	minor, rw == DISK_READ ? "read" : "write", secnum, count));
!   if (pi[minor].pi_size - secnum < count)
! 	count = pi[minor].pi_size - secnum;
    if (count <= 0)
  	return(EOF);
!   secnum += pi[minor].pi_start;
    rp->p_physio = 1;		/* disable (un)shadowing */
    dmagrab(WINCHESTER, hdcint);
    /* This loop allows a failed operation to be repeated. */
--- 308,335 ----
    drive = minor >> 3;
    if (drive < 0 || drive >= NR_DRIVES)
  	return(EIO);
! 
!   p = &pi[minor];
!   if (p->pi_size == 0)
  	return(EIO);
!   if ((mp->POSITION & SECTOR_MASK) != 0)
  	return(EINVAL);
!   secnum = (long)(mp->POSITION >> SECTOR_SHIFT);
    count = mp->COUNT;
!   if ((count & SECTOR_MASK) != 0)
  	return(EINVAL);
    rp = proc_addr(mp->PROC_NR);
    address = umap(rp, D, (vir_bytes) mp->ADDRESS, (vir_bytes) count);
    if (address == 0)
  	return(EINVAL);
!   count >>= SECTOR_SHIFT;
    TRACE(printf("hd%d: %s: sec=%D; cnt=%d\n",
  	minor, rw == DISK_READ ? "read" : "write", secnum, count));
!   if (p->pi_size - secnum < count)
! 	count = p->pi_size - secnum;
    if (count <= 0)
  	return(EOF);
!   secnum += p->pi_start;
    rp->p_physio = 1;		/* disable (un)shadowing */
    dmagrab(WINCHESTER, hdcint);
    /* This loop allows a failed operation to be repeated. */
***************
*** 334,340 ****
    rp->p_physio = 0;		/* enable (un)shadowing */
    if (r != OK)
  	return(EIO);
!   return(count * SECTOR_SIZE);
  }
  
  
--- 342,348 ----
    rp->p_physio = 0;		/* enable (un)shadowing */
    if (r != OK)
  	return(EIO);
!   return(count << SECTOR_SHIFT);
  }
  
  
*** /tmp/,RCSt1a27031	Thu Aug 24 00:02:14 1989
--- system.c	Thu Aug 17 02:06:43 1989
***************
*** 761,767 ****
  }
  
  #ifdef ATARI_ST
! #if 0
  /*===========================================================================*
   *				phys_copy				     * 
   *===========================================================================*/
--- 761,767 ----
  }
  
  #ifdef ATARI_ST
! #if 0 /* see copy68k.cpp */
  /*===========================================================================*
   *				phys_copy				     * 
   *===========================================================================*/
***************
*** 807,813 ****
    }
  }
  
! #endif
  
  /*===========================================================================*
   *				build_sig				     * 
--- 807,813 ----
    }
  }
  
! #endif /* see copy68k.cpp */
  
  /*===========================================================================*
   *				build_sig				     * 
